home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr13
/
veced100.zip
/
CONVLOAD.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-19
|
28KB
|
981 lines
// This module contains routines to perform file operations and stuff
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <alloc.h>
#include <dir.h>
#include "convdefs.h"
char filenames[20000];
/*
Here is the standard object storage protocol for files produced or loaded
using the VECEDIT vector editing program. The standard file extension
for VECEDIT objects is ".VEC"
POINTS
unsigned =number of raw points in object, if zero, terminate with error
array of long =raw points of object, stored {X,Y,Z}, {X,Y,Z} etc.
GROUP POINTS
unsigned =number of group points in object, if zero, ignore following
array of long =group points of object, stored {X,Y,Z} etc.
POLYGONS
unsigned =number of polygons in object, if zero, terminate with error
group of polygons stored as follows:
{
unsigned char =color value
unsigned =normvecoff (a multiple of 12, of course)
unsigned =pointoff (a multiple of 12, of course)
unsigned =group point "zee" offset corresponding to poly
}
NULL POLY
unsigned =offset in file used to refer to a null poly (from edgelist)
NORMALS
unsigned =number of normals in object
array of long =normals of polygons, stored {X,Y,Z}, {X,Y,Z}
EDGES
unsigned =number of edges in object, if zero, ignore following
group of edges stored as follows:
{
unsigned[2] =normalized vertex offsets (multiple of 8, from zero)
unsigned[2] =polygon offsets (multiple of 16, offset from zero)
}
*/
// read a 3D object in the above format from a file
void readobj3d(FILE *infile, numstuff *abc, unsigned *numgrps, unsigned *numnorms, unsigned nullpoly, long *rawpt, long *grppt, unsigned *grplist, polystruc *locpoly, long *rawnorms, rawedgeverts *edgees)
{
unsigned count, locdumpoly;
unsigned *tempptr;
int tempint;
// raw points
abc[0].vs=getw(infile);
if(abc[0].vs>0)
{
tempptr= (unsigned *) rawpt;
for(count=0;count<=(abc[0].vs)*6-1;count++)
{
tempptr[count]=getw(infile);
}
}
// group points
numgrps[0]=getw(infile);
if(numgrps[0]>0)
{
tempptr= (unsigned *) grppt;
for(count=0;count<=numgrps[0]*6-1;count++)
{
tempptr[count]=getw(infile);
}
}
// polygons
abc[0].ps=getw(infile);
if(abc[0].ps>0)
for(count=0;count<=abc[0].ps-1;count++)
{
locpoly[count].colorvalue=getc(infile);
locpoly[count].normvecoff=getw(infile);
locpoly[count].point =getw(infile);
locpoly[count].texflag=0;
if(numgrps[0]>0)
{
grplist[count]=getw(infile);
}
else
{
getw(infile);
}
}
// null polygon
locdumpoly=getw(infile);
// normals
numnorms[0]=getw(infile);
if(numnorms[0]>0)
{
for(count=0;count<=numnorms[0]*3-1;count++)
{
tempint=getw(infile);
rawnorms[count]=tempint;
}
}
// edges
abc[0].es=getw(infile);
if(abc[0].es>0)
for(count=0;count<=abc[0].es-1;count++)
{
edgees[count].v[0] =getw(infile);
edgees[count].v[1] =getw(infile);
edgees[count].poly[0]=getw(infile);
if(edgees[count].poly[0]==locdumpoly)
{
edgees[count].poly[0]=nullpoly;
}
else
{
edgees[count].poly[0]+=FP_OFF(locpoly);
}
edgees[count].poly[1]=getw(infile);
if(edgees[count].poly[1]==locdumpoly)
{
edgees[count].poly[1]=nullpoly;
}
else
{
edgees[count].poly[1]+=FP_OFF(locpoly);
}
edgees[count].texpoint[0]=0xFFFF;
edgees[count].texpoint[1]=0xFFFF;
}
}
/*
TEXTURE BITMAPS
Bitmaps are stored as follows, with 0xFFFF being the terminating number
{
unsigned =number of texture polys
unsigned =x size of bitmap
unsigned =y size of bitmap
char array=characters that make up bitmap
texture polys stored as follows:
{
unsigned =pointer back to polygon
texture edges stored as follows, 0xFFFF terminates texture edges
{
unsigned =back pointer to edgee
unsigned =x corner 1
unsigned =y corner 1
unsigned =x corner 2
unsigned =y corner 2
}
}
}
GOURAD TEXTURE POLYS
stored as follows, with 0xFFFF being the terminator
{
unsigned =back pointer to polygon
texedges stored as follows, with 0xFFFF being the terminating number
{
unsigned =back pointer to edge array
unsigned =goustruc pointer[0] (offset from zero)
unsigned =goustruc pointer[1] (offset from zero)
}
}
GOURAD VERTS
unsigned =number of gourad vertices
group of gourad verts stored as follows:
{
int =gvalue
unsigned =vertoff (multiple of 12, offset from zero)
unsigned =vertnormoff (multiple of 12, offset from zero)
}
VERTEX NORMALS
unsigned =number of vertex normals
array of long =vertex normals, stored {X,Y,Z}, etc.
*/
// Reads 3D texture information from a file in the above format
void readtexture3D(FILE *infile, rawedgeverts *edgees, polystruc *locpoly, texedge *texed, texstats *texts, texpoly *goutexpolys, unsigned char *bitmaparr[], unsigned *bitmapsizearray, texpoly *texpoarr[], unsigned *texpolused, unsigned *texpoltotal, gouvert *somegous, long *vertnorm, unsigned *numbmap, numstuff abc, numgoustuff *xyz)
{
unsigned count, ct2, ct3, ct4;
unsigned lastbitmapread, lasttexpolyread, lasttexedgeread, shortdum;
unsigned polyback, edgeback;
unsigned char *tempcharptr;
unsigned *tempintptr;
unsigned *intpointy;
texpoly *tempptr;
xyz[0].te=0;
xyz[0].tp=0;
xyz[0].vn=0;
// TEXTURE BITMAP LOOP
numbmap[0]=0;
lastbitmapread=getw(infile);
while(lastbitmapread!=0xFFFF)
{
// read in size of texture map
bitmapsizearray[numbmap[0]*2 ]=getw(infile);
bitmapsizearray[numbmap[0]*2+1]=getw(infile);
// Allocate memory for bitmap array and texture polys
if ((bitmaparr[numbmap[0]] = (char *) malloc(10 + bitmapsizearray[numbmap[0]*2]*bitmapsizearray[numbmap[0]*2+1] + 26*(lastbitmapread+10) )) == NULL)
{
cprintf("Not enough memory to allocate buffer\n\r");
getch();
return;
}
// set up texpoly pointer and set up texture map size info
texpoarr[numbmap[0]] =(texpoly *) MK_FP(FP_SEG(bitmaparr[numbmap[0]]),FP_OFF(bitmaparr[numbmap[0]]) + 10 + bitmapsizearray[numbmap[0]*2]*bitmapsizearray[numbmap[0]*2 + 1]);
count=0;
shortdum=bitmapsizearray[numbmap[0]*2];
while(shortdum>1)
{
count++;
shortdum/=2;
}
intpointy= (unsigned *) bitmaparr[numbmap[0]];
intpointy[0]=count;
intpointy[1]=-1;
intpointy[2]=-1<<count;
// set up used and total array
texpolused[numbmap[0]]=lastbitmapread;
texpoltotal[numbmap[0]]=lastbitmapread+10;
// read characters of bitmap
tempcharptr=bitmaparr[numbmap[0]];
for(count=0; count<bitmapsizearray[numbmap[0]*2]*bitmapsizearray[numbmap[0]*2+1]; count++)
{
tempcharptr[count+6]=getc(infile);
}
// get texture polys (there are "lastbitmapread" of them)
for(count=0; count<lastbitmapread; count++)
{
// set up ordinary polygon
polyback=getw(infile)/16;
locpoly[polyback].texflag=1;
locpoly[polyback].texpoly=MK_FP(FP_SEG(texpoarr[numbmap[0]]), FP_OFF(texpoarr[numbmap[0]]) + count*26);
// set up texture poly (texture pointer and edgesgot)
tempptr=(texpoly *) locpoly[polyback].texpoly;
tempptr[0].texture= FP_OFF(bitmaparr[numbmap[0]]);
tempptr[0].edgesgot= 0;
// loop to read texture edges
lasttexedgeread= getw(infile);
while(lasttexedgeread!=0xFFFF)
{
// set up edge back reference
edgeback=lasttexedgeread/12;
if(edgees[edgeback].texpoint[0]==0xFFFF)
{
edgees[edgeback].texpoint[0]=xyz[0].te*32 + FP_OFF(texed);
}
else
{
edgees[edgeback].texpoint[1]=xyz[0].te*32 + FP_OFF(texed);
}
// set up texture poly, edgeflag, and statloc
texed[xyz[0].te].texpo=locpoly[polyback].texpoly;
texed[xyz[0].te].edgeflag=1;
texed[xyz[0].te].statloc=xyz[0].te*16 + FP_OFF(texts);
// set up texture statistics
texts[xyz[0].te].xcorn1=getw(infile);
texts[xyz[0].te].ycorn1=getw(infile);
texts[xyz[0].te].xcorn2=getw(infile);
texts[xyz[0].te].ycorn2=getw(infile);
texts[xyz[0].te].xmax=bitmapsizearray[numbmap[0]*2 ];
texts[xyz[0].te].ymax=bitmapsizearray[numbmap[0]*2+1];
// increment counters and keep going
xyz[0].te++;
lasttexedgeread=getw(infile);
}
}
numbmap[0]++;
lastbitmapread=getw(infile);
}
// GOURAD TEXTURE POLY LOOP
lasttexpolyread=getw(infile);
while(lasttexpolyread!=0xFFFF)
{
// set up ordinary polygon
polyback=lasttexpolyread/16;
locpoly[polyback].texflag=1;
locpoly[polyback].texpoly=(void *) &goutexpolys[xyz[0].tp];
// set up texture poly (edgesgot)
goutexpolys[xyz[0].tp].edgesgot= 0;
// loop to read texture edges
lasttexedgeread= getw(infile);
while(lasttexedgeread!=0xFFFF)
{
// set up edge back reference
edgeback=lasttexedgeread/12;
if(edgees[edgeback].texpoint[0]==0xFFFF)
{
edgees[edgeback].texpoint[0]=xyz[0].te*32 + FP_OFF(texed);
}
else
{
edgees[edgeback].texpoint[1]=xyz[0].te*32 + FP_OFF(texed);
}
// set up texture poly, edgeflag, and statloc
texed[xyz[0].te].texpo=locpoly[polyback].texpoly;
texed[xyz[0].te].edgeflag=2;
texed[xyz[0].te].statloc=xyz[0].te*16 + FP_OFF(texts);
// get goustruc pointers
texts[xyz[0].te].goustruc[0]=getw(infile) + FP_OFF(somegous);
texts[xyz[0].te].goustruc[1]=getw(infile) + FP_OFF(somegous);
// increment counters and keep going
xyz[0].te++;
lasttexedgeread=getw(infile);
}
// increment counters and keep going
xyz[0].tp++;
lasttexpolyread=getw(infile);
}
// Load some gourad vertices
xyz[0].vn=getw(infile);
for(count=0; count<xyz[0].vn; count++)
{
somegous[count].gvalue=getw(infile);
somegous[count].vertoff=getw(infile);
somegous[count].vertnormoff=getw(infile);
}
// Load some vertex normals
getw(infile);
tempintptr= (unsigned *) vertnorm;
for(count=0; count<xyz[0].vn*6; count++)
{
tempintptr[count]=getw(infile);
}
// DONE AT LAST !!!!!!!!!!!!!!!!!!!!!!
}
/*
The following function is used to load and save 3D objects from a group
of files. The files are all assumed to have an extension of ".VEC".
The program asks for a directory to search for the files in and then
displays all objects and files that can be loaded.
The up and down arrow keys can be used to highlight objects, and enter
will load objects. In the save objects mode, a list of all current
objects is shown and the user can create a new file.
NOTE: FILENAMES MAY NOT BE MORE THAN 40 CHARACTERS
THE LIMIT TO NUMBER OF OBJECTS IN A DIRECTORY IS 500
*/
void load3D(numstuff *abc, unsigned *numgrps, unsigned *numnorms, unsigned nullpoly, long *rawpt, long *grppt, unsigned *grplist, polystruc *locpoly, long *rawnorms, rawedgeverts *edgees, texedge *texed, texstats *texts, texpoly *goutexpolys, unsigned char *bitmaparr[], unsigned *bitmapsizearray, gouvert *somegous, long *vertnorm, unsigned *numbmap, numgoustuff *xyz, unsigned *texpolused, unsigned *texpoltotal, texpoly *texpoarr[])
{
char maincommand; // used to accept commands
FILE *currfile; // thingy used for files
char searchdir[40]; // search directory for loading
unsigned numfound; // number of 3D object files found
unsigned count, screenoff=0, highlight=0;
unsigned shortdum;
char *tempfilename;
struct ffblk ffblk;
int done;
numstuff abcextra;
unsigned grpsextra, normsextra;
clrscr();
// LOAD OPERATIONS
cprintf("Which directory shall I search, master?\n\n\r");
cprintf("Input search path-->");
gets(searchdir);
count=0;
while(searchdir[count]!=0) count++;
if((count!=0)&&(searchdir[count-1]!='\\'))
{
searchdir[count]='\\';
count++;
}
searchdir[count ]='*';
searchdir[count+1]='.';
searchdir[count+2]='V';
searchdir[count+3]='E';
searchdir[count+4]='C';
searchdir[count+5]=0;
cprintf("\n\rSearching for files...\n\r");
done = findfirst(searchdir,&ffblk,0);
if(done!=0) { cprintf("No files found, dumbass.\n\rPress a key."); getch(); goto deallocit;}
cprintf("Loading filenames...\n\r");
numfound=0;
while (!done)
{
sprintf(&filenames[numfound*40],"%s",searchdir);
sprintf(&filenames[numfound*40 + count],"%s",ffblk.ff_name);
numfound++;
done = findnext(&ffblk);
}
updateload:
;
clrscr();
cprintf("Highlight object to load and press enter");
for(count=0;count<=23;count++)
{
if((count+screenoff)==numfound) count=25;
else
{
if(highlight==count) textattr(0x70);
cprintf("\n\r%2d. %Fs",count+screenoff,&filenames[(count+screenoff)*40]);
if(highlight==count) textattr(0x07);
}
}
getakeyload:
;
maincommand=getch();
if((maincommand>='a')&&(maincommand<='z')) maincommand=maincommand-'a'+'A';
if((maincommand<='9')&&(maincommand>='0'))
{
if(numfound>(maincommand-'0')*10)
{
highlight=maincommand-'0';
highlight*=10;
screenoff=0;
while(highlight>23)
{
highlight-=24;
screenoff+=24;
}
}
goto updateload;
}
else
switch(maincommand)
{
case 13:{
if ((currfile=fopen(&filenames[(highlight+screenoff)*40],"rb")) != NULL)
{
readobj3d(currfile, abc, numgrps, numnorms, nullpoly, rawpt, grppt, grplist, locpoly, rawnorms, edgees);
fclose(currfile);
tempfilename=&filenames[(highlight+screenoff)*40];
shortdum=0;
while(tempfilename[shortdum]!='.') shortdum++;
tempfilename[shortdum+1]='T';
tempfilename[shortdum+3]='X';
if ((currfile=fopen(&filenames[(highlight+screenoff)*40],"rb")) != NULL)
{
readtexture3D(currfile, edgees, locpoly, texed, texts, goutexpolys, bitmaparr, bitmapsizearray, texpoarr, texpolused, texpoltotal, somegous, vertnorm, numbmap, abc[0], xyz);
fclose(currfile);
cprintf("\n\n\rFile AND TEXTURE successfully loaded\n\rPress a key.\n\r");
getch();
}
else
{
cprintf("\n\n\rFile successfully loaded\n\rPress a key.\n\r");
getch();
}
tempfilename[shortdum+1]='V';
tempfilename[shortdum+3]='C';
}
else
{
cprintf("\n\n\rError opening file\n\rPress a key.\n\r");
getch();
}
goto updateload;
}
case 27:
case 'Q':
case 'X':{
return;
}
case 0 :{
maincommand=getch();
if((maincommand=='P')&&((highlight+screenoff)<numfound-1))
{
highlight++;
if(highlight>23)
{
highlight=0;
screenoff+=24;
}
goto updateload;
}
if((maincommand=='H')&&((highlight+screenoff)>0))
{
if(highlight==0)
{
highlight=24;
screenoff-=24;
}
highlight--;
goto updateload;
}
if((maincommand==73)&&(screenoff>0))
{
// Page up
screenoff-=24;
highlight=0;
goto updateload;
}
if((maincommand==81)&&((screenoff+24)<numfound-1))
{
// Page down
screenoff+=24;
highlight=0;
goto updateload;
}
goto getakeyload;
}
default :goto getakeyload;
}
deallocit:
;
}
// calculates a dot b
long dotproduct(long *a, long *b)
{
long returnval;
returnval=a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
return(returnval);
}
// calculates x dot (a cross b)-- the triple scalar product
// only the sign is accurate, though
float triplescalar(long *x, long *a, long *b)
{
float returnval, vec[3], x2[3], a2[3], b2[3];
unsigned count;
for(count=0; count<=2; count++) x2[count]= x[count];
for(count=0; count<=2; count++) a2[count]= a[count];
for(count=0; count<=2; count++) b2[count]= b[count];
vec[0]= ((a2[1]*b2[2]) - (a2[2]*b2[1]));
vec[1]=-((a2[0]*b2[2]) - (a2[2]*b2[0]));
vec[2]= ((a2[0]*b2[1]) - (a2[1]*b2[0]));
returnval= x[0]*vec[0] + x[1]*vec[1] + x[2]*vec[2];
return(returnval);
}
// Calculates the magnitude of a given vector. Might modify the magnitude
// of the given vector to prevent nasty overflow errors. The function
// will return the magnitude of the resulting vector regardless.
long magnitude(long *a)
{
unsigned ct2;
long returnval, mag, sqrtmag;
while((a[0]>32768) || (a[1]>32768) || (a[2]>32768) || (a[0]<-32768) || (a[1]<-32768) || (a[2]<-32768))
{
a[0]/=2;
a[1]/=2;
a[2]/=2;
}
mag = (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
if(mag==0) return(0);
if(mag<33554432l)
{
mag*=16;
a[0]*=4;
a[1]*=4;
a[2]*=4;
}
sqrtmag= mag/2;
for(ct2=1;ct2<=20;ct2++)
{
sqrtmag= (sqrtmag + mag/sqrtmag)/2;
}
returnval=sqrtmag+1;
return(returnval);
}
// normalize a vector to 512, the standard norm size
void normalize(long *a, long magnitude)
{
unsigned count;
for(count=0;count<=2;count++)
{
a[count]=(a[count]*512)/magnitude;
}
}
//************************************************************************
//************************************************************************
// The following routine calculates the set of vertices for a face.
// The offset for "faceverts" is the actual offset to put the info. The
// other three arrays are all offset from zero. This routine sets up
// everything except texture information.
void setupface(unsigned num, polystruc *polys, rawedgeverts *edgees, unsigned *grplist, long *rawpt, long *norms, face *thefaces, unsigned *faceverts, numstuff abc)
{
unsigned count, ct2, lastedge, vertloc=0, temp;
long vec1[3], vec2[3];
// calculate the number of points and get the location of one point
thefaces[num].numpoints=0;
for(count=0; count<abc.es; count++)
{
if(edgees[count].poly[0]==(num*16 + FP_OFF(polys)))
{
thefaces[num].numpoints++; // one point per edge
faceverts[0]=edgees[count].v[0]/8; // store a point
}
if(edgees[count].poly[1]==(num*16 + FP_OFF(polys)))
{
thefaces[num].numpoints++; // one point per edge
faceverts[0]=edgees[count].v[0]/8; // store a point
}
}
thefaces[num].pointarray=faceverts; // set up the pointarray
thefaces[num].color=polys[num].colorvalue; // set up color value
thefaces[num].normalvec=polys[num].normvecoff/12; // set up normal vec
thefaces[num].shadeflag=0; // shading flag
thefaces[num].grouppt=grplist[num]/12; // group point
lastedge=abc.es+1; // set the last edge
// seek the next point and write it until the next point==original point
do {
vertloc++;
// seek an edge!=lastedge that contains faceverts[vertloc-1] AND the poly
for(count=0; count<abc.es; count++)
{
if(count!=lastedge)
{
if((edgees[count].v[0]==faceverts[vertloc-1]*8)&&((edgees[count].poly[0]==num*16+FP_OFF(polys)) || (edgees[count].poly[1]==num*16+FP_OFF(polys))))
{
faceverts[vertloc]=edgees[count].v[1]/8;
lastedge=count;
count=abc.es+1;
}
else
if((edgees[count].v[1]==faceverts[vertloc-1]*8)&&((edgees[count].poly[0]==num*16+FP_OFF(polys)) || (edgees[count].poly[1]==num*16+FP_OFF(polys))))
{
faceverts[vertloc]=edgees[count].v[0]/8;
lastedge=count;
count=abc.es+1;
}
}
}
if(kbhit()) {getch(); return;}
} while(faceverts[vertloc]!=faceverts[0]);
// Fix the normals of the face for the "right hand rule"
startover:
vec1[0]= rawpt[thefaces[num].pointarray[0]*3 + 0] - rawpt[thefaces[num].pointarray[1]*3 + 0];
vec1[1]= rawpt[thefaces[num].pointarray[0]*3 + 1] - rawpt[thefaces[num].pointarray[1]*3 + 1];
vec1[2]= rawpt[thefaces[num].pointarray[0]*3 + 2] - rawpt[thefaces[num].pointarray[1]*3 + 2];
vec2[0]= rawpt[thefaces[num].pointarray[2]*3 + 0] - rawpt[thefaces[num].pointarray[1]*3 + 0];
vec2[1]= rawpt[thefaces[num].pointarray[2]*3 + 1] - rawpt[thefaces[num].pointarray[1]*3 + 1];
vec2[2]= rawpt[thefaces[num].pointarray[2]*3 + 2] - rawpt[thefaces[num].pointarray[1]*3 + 2];
// check to see if the vectors are collinear
normalize(vec1, magnitude(vec1));
normalize(vec2, magnitude(vec2));
if(dotproduct(vec1, vec2)<-250000l)
{
// if so, scramble the points and recalc
temp=thefaces[num].pointarray[0];
for(ct2=0; ct2<thefaces[num].numpoints-1; ct2++)
{
thefaces[num].pointarray[ct2]=thefaces[num].pointarray[ct2 + 1];
}
thefaces[num].pointarray[thefaces[num].numpoints-1]=temp;
asm jmp startover;
}
// check points with the normal vector
if(triplescalar(&norms[thefaces[num].normalvec*3], vec2, vec1)<0)
{
// scramble the points again and we are done.
temp=thefaces[num].pointarray[0];
thefaces[num].pointarray[0]=thefaces[num].pointarray[2];
thefaces[num].pointarray[2]=temp;
for(ct2=0; ct2<(thefaces[num].numpoints-3)/2; ct2++)
{
temp=thefaces[num].pointarray[ct2+3];
thefaces[num].pointarray[ct2+3]=thefaces[num].pointarray[thefaces[num].numpoints-ct2-1];
thefaces[num].pointarray[thefaces[num].numpoints-ct2-1]=temp;
}
}
}
//************************************************************************
//************************************************************************
// The following routine calculates the texture interpolation information
// for doing texture mapping and gourad shading.
void setuptexture(unsigned num, polystruc *polys, rawedgeverts *edgees, face *thefaces, numstuff abc, texedge *texed, texstats *texts, gouvert *somegous, outgou *thegous, outtex *thetexs)
{
unsigned count, ct2;
texpoly *txp;
texedge *txe;
texstats *txs;
txp=((texpoly *) polys[num].texpoly);
thefaces[num].gouvee= thegous;
thefaces[num].texvee= thetexs;
// Loop through all the vertices connected to the poly
for(count=0; count<thefaces[num].numpoints; count++)
{
// Search for an edge that contains the vertex
for(ct2=0; ct2<abc.es; ct2++)
{
if((thefaces[num].pointarray[count]==edgees[ct2].v[0]/8)&&((edgees[ct2].poly[0]==num*16+FP_OFF(polys)) || (edgees[ct2].poly[1]==num*16+FP_OFF(polys))))
{
// found a vertex...
// set up our temp pointer to the texture edge
if((edgees[ct2].texpoint[0]!=0xFFFF)&&(txp==texed[(edgees[ct2].texpoint[0]-FP_OFF(texed))/32].texpo))
{
txe=&texed[(edgees[ct2].texpoint[0]-FP_OFF(texed))/32];
}
else
{
txe=&texed[(edgees[ct2].texpoint[1]-FP_OFF(texed))/32];
}
txs=&texts[(txe[0].statloc-FP_OFF(texts))/16];
// the first time through, get bitmap/ shadeflag information
if(count==0)
{
thefaces[num].shadeflag=txe[0].edgeflag;
if(thefaces[num].shadeflag==1)
{
thefaces[num].bmp= (char *) MK_FP(FP_SEG(txp), txp[0].texture);
}
}
// Set up the rest of the information
if(thefaces[num].shadeflag==1)
{
thetexs[count].x=txs[0].xcorn1;
thetexs[count].y=txs[0].ycorn1;
}
else
{
thegous[count].vertnormal=somegous[(txs[0].goustruc[0]-FP_OFF(somegous))/6].vertnormoff/12;
}
ct2=abc.es+1;
}
if((thefaces[num].pointarray[count]==edgees[ct2].v[1]/8)&&((edgees[ct2].poly[0]==num*16+FP_OFF(polys)) || (edgees[ct2].poly[1]==num*16+FP_OFF(polys))))
{
// found a vertex...
// set up our temp pointer to the texture edge
if((edgees[ct2].texpoint[0]!=0xFFFF)&&(txp==texed[(edgees[ct2].texpoint[0]-FP_OFF(texed))/32].texpo))
{
txe=&texed[(edgees[ct2].texpoint[0]-FP_OFF(texed))/32];
}
else
{
txe=&texed[(edgees[ct2].texpoint[1]-FP_OFF(texed))/32];
}
txs=&texts[(txe[0].statloc-FP_OFF(texts))/16];
// the first time through, get bitmap/ shadeflag information
if(count==0)
{
thefaces[num].shadeflag=txe[0].edgeflag;
if(thefaces[num].shadeflag==1)
{
thefaces[num].bmp= (char *) MK_FP(FP_SEG(txp), txp[0].texture);
}
}
// Set up the rest of the information
if(thefaces[num].shadeflag==1)
{
thetexs[count].x=txs[0].xcorn2;
thetexs[count].y=txs[0].ycorn2;
}
else
{
thegous[count].vertnormal=somegous[(txs[0].goustruc[1]-FP_OFF(somegous))/6].vertnormoff/12;
}
ct2=abc.es+1;
}
}
}
}
//************************************************************************
//************************************************************************
// Converts the 3D objects to a "simpler" format.
void conv3D(numstuff *abc, long *rawpt, unsigned *grplist, polystruc *locpoly, long *rawnorms, rawedgeverts *edgees, texedge *texed, texstats *texts, gouvert *somegous, numgoustuff *xyz, face *thefaces, outgou *thegous, outtex *thetexs, unsigned *faceverts)
{
unsigned count, ct2, facevertoffs=0, tvertoffs=0, gvertoffs=0;
clrscr();
// Figure out the faces and the faceverts list (this is the hardest part)
for(count=0; count<abc[0].ps; count++)
{
setupface(count, locpoly, edgees, grplist, rawpt, rawnorms, thefaces, &faceverts[facevertoffs], abc[0]);
facevertoffs+=thefaces[count].numpoints;
}
// Figure out stuff for texture mapping
if(xyz[0].te>0) for(count=0; count<abc[0].ps; count++)
{
if(locpoly[count].texflag==1)
{
setuptexture(count, locpoly, edgees, thefaces, abc[0], texed, texts, somegous, thegous, thetexs);
tvertoffs+=thefaces[count].numpoints;
gvertoffs+=thefaces[count].numpoints;
}
cprintf("%d, ", thefaces[count].numpoints);
for(ct2=0; ct2<thefaces[count].numpoints; ct2++)
{
cprintf("%d, ", thefaces[count].pointarray[ct2]);
}
cprintf(" %d, ", (thefaces[count].color&3)+1);
if(thefaces[count].shadeflag==1)
{
cprintf("Texture map: ");
}
else
{
cprintf("Vertex normals: ");
}
for(ct2=0; ct2<thefaces[count].numpoints; ct2++)
{
if(thefaces[count].shadeflag==1)
{
cprintf("{%d,%d}, ",thefaces[count].texvee[ct2].x, thefaces[count].texvee[ct2].y);
}
else
{
cprintf("{%d}, ", thefaces[count].gouvee[ct2].vertnormal);
}
}
cprintf("\n\r");
if(getch()==27) count=abc[0].ps+1;
}
}
//************************************************************************
//************************************************************************
// Test dump of 3D object for ved04b-- you can find ved04b on x2ftp.oulu.fi
void dumpved04(numstuff abc, long *rawpt, face *thefaces)
{
unsigned count, ct2;
char *filename= "test.v04";
FILE *out;
if ((out = fopen(filename, "wt"))== NULL)
{
fprintf(stderr, "Cannot open output file.\n");
return;
}
fprintf(out, "%d,\n", abc.vs);
for(count=0; count<abc.vs; count++)
{
fprintf(out, "%ld, %ld, %ld,\n", rawpt[count*3]/4, rawpt[count*3 + 1]/4, rawpt[count*3 + 2]/4);
}
fprintf(out, "\n%d,\n", abc.ps);
for(count=0; count<abc.ps; count++)
{
fprintf(out, "%d, ", thefaces[count].numpoints);
for(ct2=0; ct2<thefaces[count].numpoints; ct2++)
{
fprintf(out, "%d, ", thefaces[count].pointarray[ct2]);
}
fprintf(out, " %d,\n", (thefaces[count].color&3)+1);
}
fclose(out);
}